Parity Bridge
bridge is able to pass arbitary messages between two ethereum-based blockchains
前提:少なくともside chainにはPoAベースの chainが利用されている
概要
Parityは、bridgeをScaling Solutionとして開発している。
具体的には、Parity bridgeを使用することで、Homeと呼ばれるetherに裏付けされているチェーン(最も分かりやすいのがethereum mainnet)と他のEVMベースのPoA(Proof of Authority)チェーンと繋ぎ込める。
まずEthereum Main net の Home bridgeコントラクトにetherをデポジットすることによって、繋いでいる方のPoAチェーンでそれと同額のetherが利用できるようにする。最後にetherをmainnetに戻し、userのEOAに返す
こうしてPoAチェーンの中でtokenを動かせるようにすることで、gasコストを二回のトランザクションでのみしか払わなくていいし、トランザクションの処理速度も速くなる。
将来的には、このparity bridgeによってPolkadotとethereumやパラチェーン以外のチェーンを繋げることを目標に開発されている。
Github
current functionality
relayMessage(bytes calldata data, address recipient):
一方のチェーンでこの関数を用いると相手型のチェーンのBridgeRecipientコントラクトが呼び出されてそこを経由してブリッジが行われる
Tomato.icon<recipientのアドレスにはsideのアドレスを入れるってことなのか?
etaro.icon < receipient のアドレスはrelayしたメッセージをもとに実行するContractのaddressを入れるマン
high level explanation of main ether -> side ERC20 relay
1:senderが " Main.relayMessage(data, recipient)を ポチッ"と実行
2: RelayMessage( messageID, sender, recipient)イベント発火
3: sideのauthorityが2のイベント発火をチェックしたら、1RelayMessageイベントにつき一回Side.acceptMessage(transactionHash, data, sender, recepient)を実行
Tomato.icon<どうやって2を感知するんですか
etaro.icon < AuthoritiesがEventをWatchしているマン
tomato.icon<どこでacceptMessageを実行するの?side chain上?
etaro.icon < That's right マン
Tomato.icon<ここにBridgeRecipientが存在するのか、、、?
etaro.icon < acceptMessage()の中でBridgeRecipientに当たるContractのfunctionを実行するマン
4: SideのAuthoritiesのうち、コンセンサスに必要な署名数が集まった(Side.requiredSignaturesに達した)段階で 、次へ
5:recipientにaddressを指定したコントラクト上のacceptMessage(data,sender)を実行する
6: AcceptedMessage(messageID, sender, recipient)が発火
high level explanation of side ERC20 -> main ether relay
1; senderが " Side.relayMessage(data, recipient) をポチッ"と実行
2: Side.RelayMessage( messageID, sender, recipient)イベント発火
3: 2を検知したsideのauthoritiesが、1RelayMessageイベントにつき一回、 Side.submitSignedMessage(signature, message)を(署名とともに)実行
tomato.icon<PoAであるside上で両方向の移動とも署名が行われる
mainはpublic想定なのでauthorityが存在しないため
4: SideのAuthoritiesのうち、コンセンサスに必要な署名数が集まった(Side.requiredSignaturesに達した)段階で Side.SignedMessage(authorityThatSubmittedLastSignature, messageHash)イベントが発火
5: 4を検知したAuthoritiesは、MessageHashから message とsignatureを取り出し、そのdataを持って、Main上のMain.acceptMessage(vs, rs, ss, transactionHash, data, sender, recipient)を実行
6: Main.acceptMessage(vs, rs, ss, transactionHash, data, sender, recipient)上で、authoritesのリストのうち、コンセンサスに必要なだけの署名数が存在するかをチェックし、OKだったら 次へ
7: recipientにaddressを指定したコントラクト上のacceptMessage(data,sender)を実行する
8: AcceptedMessage(messageID, sender, recipient)が発火
deployment guide on parity wiki
---------------------------------------------------------------------------------------------------------------------------------------------------------
Etaro.icon < 追記マン
前提: mainがether backedなchain、sideがPoAのchain、authorityがPoAのchainのvalidatorを指している
ここでは、mainをethereum main net, sideをPoAコンソーシアムチェーンとする。
どうやってBridgeしてるの?
構成要素
https://gyazo.com/00c6e37ad49c9aa612e579b49630657d
main 側のContracts
side 側のContracts
Parity Bridge
の3つ
MainからSideへのRelay
https://gyazo.com/b8516a12dfc2f0a98c778eed3d617221
SideからMainへのRelay
https://gyazo.com/14368ffe71c8da267b1dc5aeee0f2107
Initial Setup
必要なコンポーネント:
Parity Bridge (Event Watcher)
Contracts in Main chain and Side chain
1. SideのAuthoritiesのうち1人がBridge のためのContractを作成
https://gyazo.com/91f0b3e2da7ec66e9adb8e6ade2041a8
以下の設定ファイルを用意
code:bridge_config.toml
# 変更必須項目: Authority node自身の(sideにおける)address
address = "0x00bd138abd70e2f00903268f3db08f2d25677c9e"
# estimated_gas
estimated_gas_cost_of_withdraw = "200000"
# mainにdeployされるコントラクトに自身がdepositできる最高総額
# 万が一Bridgeが死んだ時の最大被害額
# 0にすると無制限になる(非推奨)
# デフォルトでは10ETHに設定されている
max_total_main_contract_balance = "10000000000000000000"
# mainにdeployされるコントラクトに一回当たりdepositできる最高額
# 0にすると無制限になる(非推奨)
# デフォルトでは1ETHに設定されている
max_single_deposit_value = "1000000000000000000"
# 変更必須項目: 自身のmain nodeへの接続先
# 変更必須項目: mainにおけるtransactionがfinalizeしたとみなすのに必要な承認数,デフォルトは 12 デプロイ時のみ必要?
required_confirmations = 0
# Mainにdeployするコントラクトをcompileしたもののpath
bin = "../compiled_contracts/Main.bin"
# 変更必須項目: 自身のside nodeへの接続先
# 変更必須項目: sideにおけるtransactionがfinalizeしたとみなすのに必要な承認数,デフォルトは 12 デプロイ時のみ必要?
required_confirmations = 0
# Sideにdeployするコントラクトをcompileしたもののpath
bin = "../compiled_contracts/Side.bin"
# 変更必須項目: PoAチェーン(side)の全validatorのaddress一覧list デプロイ時のみ必要?
accounts = [
"0x00bd138abd70e2f00903268f3db08f2d25677c9e",
]
# 変更必須項目: PoAのfinalizeに必要な署名数(基本はauthoritiesの数の2/3) デプロイ時のみ必要?
required_signatures = 1
# テスト用のデフォルトでは0
# 変更必須項目: それぞれのTransactionの際の自身のgas_priceを設定する
# these happen on main:
main_deploy = { gas = "1500000" , gas_price = "0" }
withdraw_relay = { gas = "200000" , gas_price = "0" }
# these happen on side:
side_deploy = { gas = "3000000" , gas_price = "0" }
deposit_relay = { gas = "150000" , gas_price = "0" }
withdraw_confirm = { gas = "300000" , gas_price = "0" }
2. Main, SideそれぞれにContractをDeploy
https://gyazo.com/820ed794f1344078a2025c1bc4fe159a
コマンドをぶっ叩くとparity-bridgeが1の設定に従ってよしなにデプロイ
deploy 結果として以下のようなファイル生成
code:bridge.db
home_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f"
foreign_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f"
home_deploy = 1
foreign_deploy = 1
checked_deposit_relay = 3
checked_withdraw_relay = 4
checked_withdraw_confirm = 4
3. bridge.dbの情報を他のAuthoritiesに共有
https://gyazo.com/4cc6835fc51adc2a52fcd5c827c6375a
4. 全てのAuthoritiesが起動状態に
全てのAuthoritiesがmain full node, side full node, parity bridgeを動かしたらセットアップ完了
問題点と対策
PoAにTX手数料が存在しないことによる問題
UserがSide上でrelayMessageへtokenをぶん投げると、そこから発火したeventにより、Authoritiesはmain側のacceptMessageを呼ばなくてはならないが、mainのTX実行にはether backedなgas代がかかる。
つまり、Userはなんの経済的支出もなしに、Side上のrelayMessageを呼び出しまくることによって、Authoritiesのリアルマネーを枯渇させるという攻撃ができてしまう。
対策
そもそもmain側でwithdrawが可能なuserをrecipientのwhitelistとして定義しておく
User自身でside側Authoritiesのメッセージと署名を集めさせ、main側のacceptMessageを呼ばせる
Side側でTokenをburnするなどのMainに対してRelayする処理を行う際にSide側のTokenを手数料として取る実装にする
Source